<template>
  <div class="content" id="three" ref="three">
    <!-- 背景图容器，支持拖拽和缩放 -->
    <div 
      class="background-container"
      @mousedown="startDrag"
      @mousemove="onDrag"
      @mouseup="stopDrag"
      @mouseleave="stopDrag"
      @wheel="onWheel"
      ref="bgContainer"
      v-show="backgroundImage"
    >
      <div 
        class="image-wrapper"
        :style="{ 
          transform: `translate(${imagePosition.x}px, ${imagePosition.y}px) scale(${imageScale})`,
          width: contentWidth + 'px',
          height: 'auto'
        }"
      >
        <img :src="backgroundImage" class="background-image" ref="bgImage" @load="handleImageLoad" />
        
        <!-- 设备图标 - 使用百分比定位，但大小不随缩放变化 -->
        <div 
          v-for="device in deviceData" 
          :key="device.id"
          class="device-icon"
          :style="{ 
            left: (device.posx * 100) + '%', 
            top: (device.posy * 100) + '%',
            transform: `translate(-50%, -50%) scale(${1/imageScale})` /* 抵消父元素的缩放效果 */
            /* 如需和父元素一起缩放，共两处需要处理，
            第一：注释transform: `translate(-50%, -50%) scale(${1/imageScale})`；*/
          }"
          @click="openDeviceDetailDialog(device)"
        >
          <img :src="device.iconPath" alt="设备" />
          <span class="device-name">{{ device.deviceCustomName || device.deviceName }}</span>
        </div>
      </div>
    </div>
    
    <!-- 左中右三栏内容 -->
    <left-song ref="left" class="side-panel" />
    <middle-song ref="middle" @space-selected="handleSpaceSelected" />
    <right-song ref="right" class="side-panel" />
    <!-- 设备详细信息 -->
    <DeviceDetailDialog ref="deviceDetailDialogRef" @update-icon="updateDeviceIcon" />
  </div>
</template>

<script lang="ts" setup>
// 左中右3部分内容
import LeftSong from './threeSong/left.vue'
import MiddleSong from './threeSong/middle.vue'
import RightSong from './threeSong/right.vue'
import { ref, reactive, onMounted, nextTick, onUnmounted } from 'vue'
import { listByIds } from '@/api/system/oss'
import { getSpaceDevices } from '@/views/setting/building/api/building.api'
import { devicePropertyLogs } from '@/views/setting/device/api/devices.api'
import DeviceDetailDialog from '../datavStreetLamp/components/DeviceDetailDialog.vue'
// 引入公共方法获取设备属性、判断是否为灯控设备和网关
import { getDeviceProperties, isLightController, getDeviceIconPath } from '@/utils/deviceUtils'

// 定义定时器引用
const refreshTimer = ref<number | null>(null)

const deviceDetailDialogRef =ref()

// 图片相关状态
const backgroundImage = ref<string>('') // 背景图片URL
const contentWidth = ref<number>(0) // 整个content的宽度

// 图片拖拽和缩放相关状态
const bgContainer = ref<HTMLElement | null>(null)
const isDragging = ref<boolean>(false)
const dragStart = reactive({ x: 0, y: 0 })
const imagePosition = reactive({ x: 0, y: 0 })
const imageScale = ref<number>(1)
const lastPosition = reactive({ x: 0, y: 0 })

// 设备数据
const deviceData = ref<any[]>([])
const currentSpaceId = ref<string | number | null>(null)

// 添加图片引用
const bgImage = ref<HTMLImageElement | null>(null)

// 设备状态查询相关
const stateDialog = reactive({
  row: {} as any,
  swName: '',
  slName: '',
  historyTime: [new Date(Date.now() - 24 * 60 * 60 * 1000), new Date()] as Date[], // 默认查询最近24小时
})

// 对比两个设备对象是否有差异
const isDeviceDifferent = (oldDevice: any, newDevice: any): boolean => {
  // 可根据实际需求添加更多需要对比的属性
  return (
    oldDevice.id !== newDevice.id ||
    oldDevice.posx !== newDevice.posx ||
    oldDevice.posy !== newDevice.posy ||
    oldDevice.online !== newDevice.online ||
    oldDevice.productKey !== newDevice.productKey
  );
};

// 刷新设备和设备状态的函数
const refreshDeviceData = async () => {
  if (currentSpaceId.value) {
    console.log('30s刷新设备和设备状态')
    // 更新查询时间范围为最新的 24 小时
    stateDialog.historyTime = [new Date(Date.now() - 24 * 60 * 60 * 1000), new Date()]
    await getDeviceList(currentSpaceId.value, true); // 定时刷新传入 true 进行对比
  }
}

// 打开设备详情对话框的方法
const openDeviceDetailDialog = (device) => {
  if (deviceDetailDialogRef.value) {
    // 设置当前设备到 stateDialog.row
    stateDialog.row = device
    deviceDetailDialogRef.value.openDialog(device)
  }
}


// 处理设备位置数据，确保使用百分比
const processDevicePosition = (device: any) => {
  // 如果坐标值大于1，可能是像素坐标，需要转换为百分比
  if (device.posx > 1 || device.posy > 1) {
    if (bgImage.value) {
      const imgWidth = bgImage.value.naturalWidth || 1000 // 默认宽度
      const imgHeight = bgImage.value.naturalHeight || 1000 // 默认高度
      
      // 将像素坐标转换为百分比
      device.posx = device.posx / imgWidth
      device.posy = device.posy / imgHeight
      console.log('转换设备坐标为百分比:', device.id, device.posx, device.posy)
    }
  }
  // 确保坐标是有效值
  device.posx = device.posx || 0
  device.posy = device.posy || 0
  
  return device
}

// 开关历史数据查询
const swHistory = (device: any) => {
  if (!stateDialog.swName) return Promise.resolve(0)
  
  const end = stateDialog.historyTime[1]
  const start = stateDialog.historyTime[0]
  
  return devicePropertyLogs({
    deviceId: device.deviceId,
    name: stateDialog.swName,
    start: start.getTime(),
    end: end.getTime(),
  }).then((res) => {
    if (res.data && res.data.length > 0) {
      return Number(res.data[0].value)
    } else {
      return 0
    }
  }).catch(() => {
    return 0
  })
}

// 更新单个设备图标状态
const updateDeviceIcon = (switchState: number) => {
  if (!deviceData.value || deviceData.value.length === 0 || !stateDialog.row) return
  
  const device = deviceData.value.find(d => d.id === stateDialog.row.id)
  if (!device) return
  
  device.iconPath = getDeviceIconPath(device.productKey, device.online, switchState)
}

// 更新设备图标状态
const updateDeviceIcons = async () => {
  // 对所有设备设置图标
  for (const device of deviceData.value) {
    const productKey = device.productKey

    let switchState: number | undefined 
    // 灯控制器设备需要查询开关状态
    if (isLightController(productKey) && device.online) {
      const { swName, slName } = getDeviceProperties(productKey)
      stateDialog.swName = swName
      stateDialog.slName = slName
      try {
        switchState = await swHistory(device)
      } catch (error) {
        console.error('查询设备状态失败:', error)
      }
    }
    // 调用公共方法获取图标路径
    device.iconPath = getDeviceIconPath(productKey, device.online, switchState)
  }
}

// 获取设备列表
const getDeviceList = async (spaceId: string | number, isTimedRefresh: boolean = false) => {
  if (!spaceId) return
  
  try {
    const res = await getSpaceDevices(spaceId)
    if (res.code === 200) {
      const newAllDevices = res.data || []
      const newFilteredDevices = newAllDevices
        .filter(device => 
          device.posx && device.posy && 
          (device.posx !== 0 || device.posy !== 0)
        )
        .map(device => processDevicePosition(device))
      
      if (isTimedRefresh) {
        console.log('设备列表定时更新:', deviceData.value)
        
        const updatedDevices: any[] = []

        // 遍历新设备列表
        for (const newDevice of newFilteredDevices) {
          const existingIndex = deviceData.value.findIndex(d => d.id === newDevice.id)
          if (existingIndex !== -1) {
            const existingDevice = deviceData.value[existingIndex]
            if (isDeviceDifferent(existingDevice, newDevice)) {
              // 设备有变化，使用新数据
              updatedDevices.push(newDevice)
            } else {
              // 设备无变化，使用旧数据
              updatedDevices.push(existingDevice)
            }
          } else {
            // 新设备，添加到更新列表
            updatedDevices.push(newDevice)
          }
        }

        // 处理已移除的设备
        const newDeviceIds = new Set(newFilteredDevices.map(d => d.id))
        deviceData.value = deviceData.value.filter(d => {
          if (newDeviceIds.has(d.id)) {
            return false
          }
          return true
        }).concat(updatedDevices)
        console.log('设备更新:', updatedDevices)
      } else {
        // 非定时刷新（如首次加载或切换空间）直接更新
        deviceData.value = newFilteredDevices
        console.log('设备列表非定时更新:', deviceData.value)
        
      }
      await updateDeviceIcons()
    }
  } catch (error) {
    console.error('获取设备列表失败:', error)
  }
}

// 图片加载完成处理器
const handleImageLoad = () => {
  if (deviceData.value.length > 0 && bgImage.value) {
    // 再次处理所有设备的位置信息，确保使用百分比
    deviceData.value = deviceData.value.map(device => processDevicePosition(device))
  }
}

// 获取content元素的宽度
const updateContentWidth = () => {
  const contentElement = document.getElementById('three')
  if (contentElement) {
    contentWidth.value = contentElement.offsetWidth
  }
}

// 窗口大小变化时更新宽度
const handleResize = () => {
  updateContentWidth()
}

// 开始拖拽
const startDrag = (e: MouseEvent) => {
  if (!backgroundImage.value) return
  
  isDragging.value = true
  dragStart.x = e.clientX
  dragStart.y = e.clientY
  lastPosition.x = imagePosition.x
  lastPosition.y = imagePosition.y
  
  // 改变鼠标样式
  if (bgContainer.value) {
    bgContainer.value.style.cursor = 'grabbing'
  }
}

// 拖拽中
const onDrag = (e: MouseEvent) => {
  if (!isDragging.value) return
  
  // 计算移动距离
  const dx = e.clientX - dragStart.x
  const dy = e.clientY - dragStart.y
  
  // 更新图片位置
  imagePosition.x = lastPosition.x + dx
  imagePosition.y = lastPosition.y + dy
}

// 停止拖拽
const stopDrag = () => {
  isDragging.value = false
  
  // 恢复鼠标样式
  if (bgContainer.value) {
    bgContainer.value.style.cursor = 'grab'
  }
}

// 滚轮缩放
const onWheel = (e: WheelEvent) => {
  if (!backgroundImage.value) return
  
  e.preventDefault()
  
  // 缩放系数
  const scaleFactor = e.deltaY > 0 ? 0.9 : 1.1
  
  // 计算新的缩放值，并限制范围
  const newScale = Math.max(0.5, Math.min(5, imageScale.value * scaleFactor))
  
  // 获取鼠标在图片上的相对位置
  const rect = bgContainer.value?.getBoundingClientRect()
  if (!rect) return
  
  const mouseX = e.clientX - rect.left
  const mouseY = e.clientY - rect.top
  
  // 计算鼠标位置相对于图片中心的偏移
  const offsetX = mouseX - rect.width / 2
  const offsetY = mouseY - rect.height / 2
  
  // 根据缩放比例调整偏移量
  const scaleChange = newScale - imageScale.value
  imagePosition.x -= offsetX * (scaleChange) / imageScale.value
  imagePosition.y -= offsetY * (scaleChange) / imageScale.value
  
  // 更新缩放值
  imageScale.value = newScale
}

// 处理空间选择
const handleSpaceSelected = async (space: { id: string | number, name: string, ossId?: string | number } | null) => {
  // 重置图片位置和缩放
  imagePosition.x = 0
  imagePosition.y = 0
  imageScale.value = 1
  
  // 清空设备数据
  deviceData.value = []
  
  if (space && space.ossId) {
    // 更新当前空间ID
    currentSpaceId.value = space.id
    
    await loadBackgroundImage(space.ossId)
    
    await getDeviceList(space.id, false) // 非定时刷新传入 false
    console.log('选择空间:', space.name, 'OSS ID:', space.ossId)
  } else {
    backgroundImage.value = ''
    currentSpaceId.value = null
  }
}

// 加载背景图片
const loadBackgroundImage = async (ossId: string | number) => {
  try {
    const res = await listByIds(ossId)
    if (res && res.code === 200 && res.data && res.data.length > 0) {
      backgroundImage.value = res.data[0].url
      
      // 确保内容宽度已更新
      await nextTick()
      updateContentWidth()
    } else {
      backgroundImage.value = ''
    }
  } catch (error) {
    console.error('加载背景图片失败:', error)
    backgroundImage.value = ''
  }
}

onMounted(() => {
  // 设置初始鼠标样式
  if (bgContainer.value) {
    bgContainer.value.style.cursor = 'grab'
  }
  
  // 获取content宽度
  updateContentWidth()
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)

  // 立即执行一次刷新
  refreshDeviceData()
  // 开启 20 秒定时刷新
  refreshTimer.value = window.setInterval(refreshDeviceData, 15000)
})

// 组件卸载时移除事件监听
onUnmounted(() => {
  window.removeEventListener('resize', handleResize)

  if (refreshTimer.value) {
    window.clearInterval(refreshTimer.value)
  }
})
</script>

<style lang="scss" scoped>
.content {
  width: 100%;
  flex: 1 1 auto;
  overflow: hidden; /* 修改为hidden避免图片溢出 */
  display: flex;
  justify-content: space-between;
  position: relative;
}

/* 左右两侧面板添加半透明效果 */
.side-panel {
  position: relative;
  z-index: 5;
  // background-color: rgba(255, 255, 255, 0.7); /* 添加半透明背景 */
}

.background-container {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
  z-index: 1; /* 设置为最底层 */
  
  &:hover {
    cursor: grab;
  }
  
  &:active {
    cursor: grabbing;
  }
}

.image-wrapper {
  transform-origin: center;
  transition: transform 0.05s ease;
  position: relative;
}

.background-image {
  width: 100%;
  height: auto;
  display: block;
  user-select: none;
}

/* 设备图标样式 */
.device-icon {
  position: absolute;
  cursor: pointer;
  z-index: 2;
  /* transform 移到了内联样式中，以便动态计算反缩放值 */
  transform-origin: center center; /* 使设备图标中心点对准指定位置，但设备图标不随图片缩放一起缩放 */
  /* 如果需要设备图标和图片（即父元素）一起缩放，共两处需要处理，
  第二：注释掉transform-origin: center center;使用transform: translate(-50%, -50%)。 */
  
  img {
    width: 32px;
    height: 32px;
    object-fit: contain;
  }
  
  .device-name {
    position: absolute;
    bottom: -20px;
    left: 50%;
    transform: translateX(-50%);
    white-space: nowrap;
    font-size: 12px;
    background-color: rgba(0, 0, 0, 0.6);
    color: white;
    padding: 2px 4px;
    border-radius: 2px;
  }
}
</style>
